Index: main/plugin-cms/sitemap.xmap =================================================================== --- main/plugin-cms/sitemap.xmap (revision 26960) +++ main/plugin-cms/sitemap.xmap (working copy) @@ -39,6 +39,7 @@ <map:generator name="common-metadataset" src="org.ametys.cms.contenttype.CommonMetadataSetNamesGenerator"/> <map:generator name="common-metadataset-from-contents" src="org.ametys.cms.contenttype.CommonMetadataSetNamesFromContentsGenerator"/> <map:generator name="common-metadata" src="org.ametys.cms.contenttype.CommonMetadataGenerator"/> + <map:generator name="common-typed-metadata" src="org.ametys.cms.contenttype.CommonTypedMetadataGenerator"/> <map:generator name="common-sortable-metadata" src="org.ametys.cms.contenttype.CommonSortableMetadataGenerator"/> <map:generator name="profile-rights" src="org.ametys.cms.rights.ProfileRightsGenerator"/> @@ -359,6 +360,14 @@ <map:serialize type="xml"/> </map:match> + <map:match pattern="common-typed-metadata"> + <map:generate type="common-typed-metadata"/> + <map:transform type="i18n" label="xml"> + <map:parameter name="locale" value="{locale:locale}"/> + </map:transform> + <map:serialize type="xml"/> + </map:match> + <map:match pattern="common-sortable-metadata"> <map:generate type="common-sortable-metadata"/> <map:transform type="i18n" label="xml"> Index: main/plugin-cms/i18n/messages_en.xml =================================================================== --- main/plugin-cms/i18n/messages_en.xml (revision 26960) +++ main/plugin-cms/i18n/messages_en.xml (working copy) @@ -1017,6 +1017,9 @@ <message key="WIDGET_RICH_TEXT_HIERARCHY_ERROR">The title hierarchy is invalid.</message> <message key="WIDGET_RICH_TEXT_TOC_ERROR">Some text is present on the same line as a table of contents.</message> + <message key="WIDGET_SELECTTYPEDMETADATA_FILTER_NONE">None</message> + <message key="WIDGET_SELECTTYPEDMETADATA_FILTER_LOAD_ERROR">An error occurred in the loading of the metadatas</message> + <message key="WIDGET_COMBOBOX_ALL_OPTIONS">- All -</message> <!-- + Index: main/plugin-cms/i18n/messages_fr.xml =================================================================== --- main/plugin-cms/i18n/messages_fr.xml (revision 26960) +++ main/plugin-cms/i18n/messages_fr.xml (working copy) @@ -1018,6 +1018,9 @@ <message key="WIDGET_RICH_TEXT_HIERARCHY_ERROR">La hiérarchie des titres est incorrecte.</message> <message key="WIDGET_RICH_TEXT_TOC_ERROR">Du texte est présent sur la même ligne qu'une table des matières.</message> + <message key="WIDGET_SELECTTYPEDMETADATA_FILTER_NONE">Aucune</message> + <message key="WIDGET_SELECTTYPEDMETADATA_FILTER_LOAD_ERROR">Il y a eu une erreur dans le chargement des métadatas</message> + <message key="WIDGET_COMBOBOX_ALL_OPTIONS">- Tous -</message> <!-- + Index: main/plugin-cms/resources/js/org/ametys/cms/widgets/SelectTypedMetadata.i18n.js =================================================================== --- main/plugin-cms/resources/js/org/ametys/cms/widgets/SelectTypedMetadata.i18n.js (revision 0) +++ main/plugin-cms/resources/js/org/ametys/cms/widgets/SelectTypedMetadata.i18n.js (revision 0) @@ -0,0 +1,140 @@ +/* + * Copyright 2014 Anyware Services + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +Ext.namespace('org.ametys.cms.widgets'); + +//Register widget +org.ametys.utils.Widgets.registerWidget ('string', 'typed-metadata', 'org.ametys.cms.widgets.SelectTypedMetadata'); + +org.ametys.cms.widgets._metadataSetName = "index"; + +org.ametys.cms.widgets.SelectTypedMetadata = function(config, enumeratedValues) +{ + this.store = new Ext.data.SimpleStore({ + idIndex: 0, + fields: [ + {name: 'value'}, + {name: 'label'} + ] + }); + + this._metadataSetName = org.ametys.cms.widgets._metadataSetName; + + org.ametys.cms.widgets.SelectTypedMetadata.superclass.constructor.call(this, config, enumeratedValues); +}; + +Ext.extend(org.ametys.cms.widgets.SelectTypedMetadata, org.ametys.form.ComboField, { + height: 107, + width: 100, + minChars: 0, + triggerAction: 'all', + forceSelection: true, + selectOnFocus: true, + valueField: 'value', + displayField: 'label', + mode: 'local' +}); + +/** + * Force expand on focus + */ +org.ametys.cms.widgets.SelectTypedMetadata.prototype._onFocus = function () +{ + if(this.triggerAction == 'all') + { + this.doQuery(this.allQuery, true); + } + else + { + this.doQuery(this.getRawValue()); + } +} + +org.ametys.cms.widgets.SelectTypedMetadata.prototype.onSelectContentTypes = function (cTypes) +{ + this._cTypes = cTypes; + this._metadataSetName = org.ametys.cms.widgets._metadataSetName; + this._loadSkins(); +} + +org.ametys.cms.widgets.SelectTypedMetadata.prototype.onRender = function(ct, position) +{ + org.ametys.cms.widgets.SelectTypedMetadata.superclass.onRender.call(this, ct, position); + this._loadSkins(); + + this.addListener('focus', this._onFocus, this); + + org.ametys.cms.widgets.ContentTypesWidget.registerListener (this); +} + +org.ametys.cms.widgets.SelectTypedMetadata.prototype._loadSkins = function () +{ + params = {}; + params.ids = this._cTypes; + params.metadataSetName = this._metadataSetName; + + var firstLoad = false; + if (typeof this._cTypes == 'undefined') + { + firstLoad = true; + } + + var serverMessage = new org.ametys.servercomm.ServerMessage('cms', '/common-typed-metadata', params, org.ametys.servercomm.ServerComm.PRIORITY_MAJOR, this._loadSkinsCb, this, [firstLoad]); + org.ametys.servercomm.ServerComm.getInstance().send(serverMessage); +} + +org.ametys.cms.widgets.SelectTypedMetadata.prototype._loadSkinsCb = function (response, args) +{ + if (org.ametys.servercomm.ServerComm.handleBadResponse("<i18n:text i18n:key="WIDGET_SELECTTYPEDMETADATA_FILTER_LOAD_ERROR"/>", response, "org.ametys.web.administration.SkinsWidget")) + { + return; + } + + var store = this.getStore(); + store.removeAll(); + + var metadataTab = []; + + var metadatas = response.selectNodes("metadata/metadata"); + + var noData = { + value: "", + label: "<i18n:text i18n:key="WIDGET_SELECTTYPEDMETADATA_FILTER_NONE"/>" + }; + metadataTab.push(new this.store.recordType(noData)); + + for (var i=0; i < metadatas.length; i++) + { + var data = { + value: metadatas[i].getAttribute('name'), + label: metadatas[i].selectSingleNode('label')[org.ametys.servercomm.ServerComm.xmlTextContent] + }; + + metadataTab.push(new this.store.recordType(data)); + } + + this.store.add(metadataTab); + + // We set the value after the loading of the store + this.setValue(this.getValue()); + + // Check if it's the first time we load (cType is not defined before first load) + var firstLoad = args[0]; + if (!firstLoad && this.store.find('value',this.getValue()) == -1 ) + { + this.setValue(""); + } +} \ No newline at end of file Index: main/plugin-cms/src/org/ametys/cms/contenttype/CommonTypedMetadataGenerator.java =================================================================== --- main/plugin-cms/src/org/ametys/cms/contenttype/CommonTypedMetadataGenerator.java (revision 0) +++ main/plugin-cms/src/org/ametys/cms/contenttype/CommonTypedMetadataGenerator.java (revision 0) @@ -0,0 +1,232 @@ +/* + * Copyright 2010 Anyware Services + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.ametys.cms.contenttype; + +import java.io.IOException; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + +import org.apache.avalon.framework.service.ServiceException; +import org.apache.avalon.framework.service.ServiceManager; +import org.apache.cocoon.ProcessingException; +import org.apache.cocoon.environment.ObjectModelHelper; +import org.apache.cocoon.environment.Request; +import org.apache.cocoon.generation.ServiceableGenerator; +import org.apache.cocoon.xml.AttributesImpl; +import org.apache.cocoon.xml.XMLUtils; +import org.apache.commons.lang.ArrayUtils; +import org.apache.commons.lang.StringUtils; +import org.xml.sax.SAXException; + +import org.ametys.cms.lucene.FieldNames; +import org.ametys.runtime.util.I18nizableText; + +/** + * SAX common metadata given content types and metadata-set + */ +public class CommonTypedMetadataGenerator extends ServiceableGenerator +{ + /** The content type extension point */ + protected ContentTypeExtensionPoint _contentTypeEP; + + @Override + public void service(ServiceManager smanager) throws ServiceException + { + super.service(smanager); + _contentTypeEP = (ContentTypeExtensionPoint) smanager.lookup(ContentTypeExtensionPoint.ROLE); + } + + @Override + public void generate() throws IOException, SAXException, ProcessingException + { + Request request = ObjectModelHelper.getRequest(objectModel); + + String paramIds = request.getParameter("ids"); + String metadataSetName = request.getParameter("metadataSetName"); + String authorizedMetadataTypesAsString = "date"; // todo Should be a request parameter + + String[] authorizedMetadataTypes = StringUtils.split(authorizedMetadataTypesAsString); + + boolean hasDocument = false; + + String[] ids = null; + if (!StringUtils.isEmpty(paramIds)) + { + ids = paramIds.split(","); + } + else + { + ids = getAllAvailablesContentTypes(request, true); + hasDocument = true; + } + + Map<String, I18nizableText> metadataLabels = new HashMap<String, I18nizableText>(); + Map<String, MetadataType> commonMetadataNames = null; + + if (StringUtils.isNotEmpty(metadataSetName)) + { + for (String id : ids) + { + ContentType contentType = _contentTypeEP.getExtension(id); + + // Documents are not a content-type + if (!id.equals("resource")) + { + MetadataSet metadataSet = contentType.getMetadataSetForView(metadataSetName); + + // Test if the metadataSetName view is defined + if (metadataSet != null) + { + Map<String, MetadataType> metadataNames = new HashMap<String, MetadataType>(); + _getTypedMetadata(contentType, metadataSet, authorizedMetadataTypes, metadataNames, metadataLabels); + + if (commonMetadataNames == null) + { + commonMetadataNames = metadataNames; + } + else + { + // Maps intersection + commonMetadataNames.keySet().retainAll(metadataNames.keySet()); + } + } + } + else + { + hasDocument = true; + } + } + } + + saxCommonMetadata (commonMetadataNames, metadataLabels, hasDocument); + } + + private void _getTypedMetadata(MetadataDefinitionHolder metadataDefHolder, MetadataSetElement metadataSetElement, String[] authorizedMetadataTypes, Map<String, MetadataType> metadataNames, Map<String, I18nizableText> metadataLabels) + { + for (MetadataSetElement subMetadataSetElement : ((Fieldset) metadataSetElement).getElements()) + { + if (metadataSetElement instanceof MetadataDefinitionReference) + { + String metadataName = ((MetadataDefinitionReference) subMetadataSetElement).getMetadataName(); + MetadataDefinition metaDef = metadataDefHolder.getMetadataDefinition(metadataName); + // todo String metadataId = metaDef.getId(); + + if (ArrayUtils.contains(authorizedMetadataTypes, metaDef.getType())) + { + metadataNames.put(metadataName, metaDef.getType()); + + I18nizableText label = metaDef.getLabel(); + metadataLabels.put(metadataName, label); + } + + if (metaDef.getType() == MetadataType.COMPOSITE) // todo is repeater included ? + { + // TODO + } + } + else + { + // TODO + // _getTypedMetadata(metadataDefHolder, subMetadataSetElement, authorizedMetadataTypes, metadataNames, metadataLabels); + } + } + } + + /** + * SAX the common metadata + * @param commonMetadataNames the name of metadata to SAX + * @param metadataLabels all metadata labels + * @param hasDocument true if there is documents in between + * @throws SAXException if an error occurred while saxing + */ + protected void saxCommonMetadata (Map<String, MetadataType> commonMetadataNames, Map<String, I18nizableText> metadataLabels, boolean hasDocument) throws SAXException + { + contentHandler.startDocument(); + XMLUtils.startElement(contentHandler, "metadata"); + + // If "Document" is not selected in the list + if (!hasDocument) + { + Map<String, I18nizableText> commonMetadata = new HashMap<String, I18nizableText>(); + + if (metadataLabels != null && commonMetadataNames != null) + { + for (String metadataName : metadataLabels.keySet()) + { + if (commonMetadataNames.containsKey(metadataName)) + { + commonMetadata.put(metadataName, metadataLabels.get(metadataName)); + } + } + + for (String name : commonMetadata.keySet()) + { + AttributesImpl attrs = new AttributesImpl(); + attrs.addCDATAAttribute("name", name); + + MetadataType metadataType = commonMetadataNames.get(name); + attrs.addCDATAAttribute("type", metadataType.toString()); + + XMLUtils.startElement(contentHandler, "metadata", attrs); + commonMetadata.get(name).toSAX(contentHandler, "label"); + XMLUtils.endElement(contentHandler, "metadata"); + } + } + + // Always add "Last validation" + AttributesImpl attrs = new AttributesImpl(); + attrs.addAttribute("", "name", "name", "CDATA", FieldNames.LAST_VALIDATION); + attrs.addAttribute("", "type", "type", "CDATA", MetadataType.DATE.toString()); + XMLUtils.startElement(contentHandler, "metadata", attrs); + new I18nizableText("plugin.web", "PLUGINS_WEB_LAST_VALIDATION_DATE").toSAX(contentHandler, "label"); + XMLUtils.endElement(contentHandler, "metadata"); + } + + // Always add "Last modified" + AttributesImpl attrs = new AttributesImpl(); + attrs.addAttribute("", "name", "name", "CDATA", FieldNames.LAST_MODIFIED); + attrs.addAttribute("", "type", "type", "CDATA", MetadataType.DATE.toString()); + XMLUtils.startElement(contentHandler, "metadata", attrs); + new I18nizableText("plugin.web", "PLUGINS_WEB_LAST_MODIFICATION_DATE").toSAX(contentHandler, "label"); + XMLUtils.endElement(contentHandler, "metadata"); + + XMLUtils.endElement(contentHandler, "metadata"); + contentHandler.endDocument(); + } + + /** + * Get all the available content types + * @param request the request + * @param publicOnly Only the non private content types will be returned + * @return all the available content types + */ + protected String[] getAllAvailablesContentTypes (Request request, boolean publicOnly) + { + Set<String> publicTypes = new HashSet<String>(); + + for (String id : _contentTypeEP.getExtensionsIds()) + { + if (!publicOnly || !_contentTypeEP.getExtension(id).isPrivate()) + { + publicTypes.add(id); + } + } + + return publicTypes.toArray(new String[publicTypes.size()]); + } +} \ No newline at end of file